#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QTextCodec>
#include <QMessageBox>
#include <QUrl>
#include <QTextStream>
#include <QString>
#include <QFileInfo>

const QUrl Url = QObject::tr("http://127.0.0.1/UpdataList.txt");
const QString LocalInformationFileName = QObject::tr("version");
const QString UpdataListFileName = QObject::tr("UpdataList.txt");
const QString NeedUpdataListFileNameLocal = QObject::tr("list.txt");
bool IsVesUpdata(QString v1, QString v2)
{
    QStringList verInfoNum1 = v1.split('.');
    QStringList verInfoNum2 = v2.split('.');
    for(QStringList::iterator num1 = verInfoNum1.begin(), num2 = verInfoNum2.begin();
        num1 != verInfoNum1.end() && num2 != verInfoNum2.end();
        ++num1,++num2)
    {
        bool ok;
        int n1 = num1->toInt(&ok, 10);
        if(!ok)
            return false;

        int n2 = num2->toInt(&ok, 10);
        if(!ok)
            return false;

        if(n1 == n2)
            continue;
        else
        if(n1 > n2)
            return true;
        else
            return false;
    }
    return true;//表示完全相同
}

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
    fileManager = nullptr;
    init();
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::init()
{
    QFile *file = new QFile(LocalInformationFileName);
    if(!file->open(QFile::OpenModeFlag::ReadOnly))
    {
        delete file;
        file = nullptr;
        if(QMessageBox::question(this, tr("文件错误"), tr("初始化信息读取错误!")))
        {
            vers = "1.1.0";
            return;
        }
    }
    QTextStream in(file);
    vers = in.readLine();

    file->close();
    delete file;
}

void MainWindow::on_StartGame_clicked()
{
    fileManager = new downloadHelper();

    connect(fileManager, SIGNAL(SendMessageFileDownEnd()), this, SLOT(GetMessageFileDownEnd()));
    connect(this, SIGNAL(SendUpdataOver()), this, SLOT(GetUpdataOver()));
    fileManager->downloadFile(Url);
    ui->StartGame->setEnabled(false);
    firstReadLocalUpdataFile = false;
}

void MainWindow::LocalReadUpdata()
{
    QFile *file = new QFile(UpdataListFileName);
    if(!file->open(QFile::OpenModeFlag::ReadOnly))
    {
        delete file;
        file = nullptr;
        if(QMessageBox::question(this, tr("文件错误"), tr("更新列表读取失败!")))
            exit(0);//退出程序
    }
    QTextStream in(file);
        while (!in.atEnd()) {
            QString version = in.readLine();
            QString url = in.readLine();
            //处理比较此文件是否需要更新
            if(!IsVesUpdata(vers, version))
            {
                UpdataList.push_back(qMakePair(version, url));
            }
        }
    file->close();
    delete file;

}


void MainWindow::GetMessageFileDownEnd()
{
    if(!firstReadLocalUpdataFile)
    {
        //进行读取本地更新列表,并根据版本号排序
        LocalReadUpdata();
        firstReadLocalUpdataFile = true;
        if(UpdataList.empty())
            emit SendUpdataOver();
        else
            downloadProcess();
    }
    else if(UpdataList.empty())
    {
        emit SendUpdataOver();
    }
    else
    {
        downloadProcess();
    }
}

void MainWindow::downloadProcess()
{
    const QPair<QString, QUrl> &first = UpdataList.first();
    fileManager->downloadFile(first.second);
    vers = first.first;//提前更新内存中版本，但并未写入

    QFileInfo info(first.second.path());
    listFileName.push_back(info.fileName());//获得更新文件名

    UpdataList.pop_front();
}

void MainWindow::GetUpdataOver()
{
    //下载文件全部结束，现在是收尾工作
    if(fileManager)
    {
        delete fileManager;
        fileManager = nullptr;
    }

    if(!listFileName.empty())
    {
        //输出需解压的列表
        WriteInformation(NeedUpdataListFileNameLocal, listFileName);
        //解压数据包
        QString program = tr("./7za.exe");
        QStringList arguments;
        arguments << "e" << "-aoa" << "-an" << tr("-ai@%1").arg(NeedUpdataListFileNameLocal);
        if(!myProcess.startDetached(program, arguments))
        {
            QMessageBox::question(this, tr("文件错误"), tr("解压文件出错..."));
            exit(0);
        }
    }
    //删除更新列表
    QFile::remove(UpdataListFileName);
    //写入信息文件
    WriteInformation(LocalInformationFileName, QStringList(vers));

    //启动游戏
    ui->StartGame->setEnabled(true);
}

bool MainWindow::WriteInformation(QString fileName, QStringList listData)
{
    if(QFile::exists(fileName))
     {
         //qDebug() << tr("删除存在文件 %1\n").arg(fileName);
         QFile::remove(fileName);
     }
    QFile *file = new QFile(fileName);

    if(!file->open(QFile::OpenModeFlag::WriteOnly))
    {
        delete file;
        file = nullptr;
        if(QMessageBox::question(this, tr("错误信息"), tr("创建文件 %1 失败!").arg(fileName)))
            return false;
    }
    QTextStream out(file);
    for(QStringList::iterator begin = listData.begin(); begin != listData.end(); ++begin)
    {
        out << *begin << "\n";
    }

    file->flush();
    file->close();
    delete file;
    return true;
}
